﻿/**
 * ImageViewer, Version 3.
 * An on-screen rectangular region for displaying a loaded image. 
 * Updates at: http://www.moock.org/eas2/examples/.
 *
 * @author: Colin Moock
 * @modified: Marc Lin 04302007
 * @version: 2.0.0
 */
import LuminicBox.Log.*;
import com.marc.preloader.*;
import com.gskinner.event.GDispatcher;

class com.marc.imageContent.ImageViewer implements Preloadable {
	
  // The movie clip that will contain the all com.marc.imageContent.ImageViewer assets.
  private var container_mc:MovieClip;
  // The movie clip to which the container_mc will be attached.
  private var target_mc:MovieClip;

  // Depths for visual assets.
  	public var filename:String;
	public var ow:Number;
	public var oh:Number;
	public var dataLoaded:Number;
	public var dataTotal:Number;
	public var mask_w:Number;
	public var mask_h:Number;
    private var containerDepth:Number;  
    private var imageDepth:Number = 0;
    private var maskDepth:Number = 1;
   
    private var statusDepth:Number = 3;
	public var preloader:Preloader;
  // The MovieClipLoader instance used to load the image.
    private var imageLoader:MovieClipLoader;

  /**
   * com.marc.imageContent.ImageViewer Constructor
   *
   * @param   target   The movie clip to which the
   *                   com.marc.imageContent.ImageViewer will be attached.
   * @param   depth    The depth in target on which to 
   *                   attach the viewer.
   * @param   x        The horizonatal position of the viewer.
   * @param   y        The vertical position of the viewer.
   * @param   w        The width of the viewer, in pixels.
   * @param   h        The height of the viewer, in pixels.
   *                   
   */
    var log:Logger;
  public function ImageViewer (target:MovieClip, 
                               depth:Number,
                               _filename:String, 
                               x:Number, 
                               y:Number, 
                               w:Number, 
                               h:Number,
                               cbFunction:String){
 
	// add TracePublisher
	// log.addPublisher( new TracePublisher() );
	// add ConsolePublisher
	log = new Logger("myLogger");
	log.addPublisher( new ConsolePublisher() );
	filename = _filename;
    // Assign property values.
    target_mc = target;
    containerDepth = depth;
    mask_w=w;
    mask_h=h;
    imageLoader = new MovieClipLoader();
    // Register this instance to receive  events
    // from the imageLoader instance.
    imageLoader.addListener(this);

    // Set up the visual assets for this com.marc.imageContent.ImageViewer.
    buildViewer(x, y);
  }

  /**
   * Creates the onscreen assets for this com.marc.imageContent.ImageViewer.
   * The movie clip hierarchy is:
   *  [d]: container_mc
   *         2: border_mc
   *         1: mask_mc (masks image_mc)
   *         0: image_mc
   * where [d] is the user-supplied depth passed to the constructor.
   *
   * @param   x   The horizonatal position of the viewer.
   * @param   y   The vertical position of the viewer.
   * @param   w   The width of the viewer, in pixels.
   * @param   h   The height of the viewer, in pixels.
   */
  private function buildViewer (x:Number, 
                                y:Number
		                        ):Void {
      // Create the clips to hold the image, mask, and border.
      createMainContainer(x, y);
      createImageClip();
      
  }

  /**
   * Creates a movie clip, container_mc, to contain 
   * the com.marc.imageContent.ImageViewer visual assests.
   *
   * @param   x   The horizonatal position of the 
   *              container_mc movie clip.
   * @param   y   The vertical position of the 
   *              container_mc movie clip.
   */
  private function createMainContainer (x:Number, y:Number):Void {
    container_mc = target_mc.createEmptyMovieClip("container_mc" + containerDepth, containerDepth);
    container_mc._x = x;
    container_mc._y = y;
  }

  /**
   * Creates the clip into which the image is actually loaded.
   */
  private function createImageClip ():Void {
    container_mc.createEmptyMovieClip("image_mc", imageDepth);
  }

  /**
   * Creates the mask over the image. Note that this method does
   * not actually apply the mask to the image clip because a clip's
   * mask is lost when new content is loaded into it. Hence, the mask
   * is applied from onLoadInit().
   *
   * @param   w   The width of the mask, in pixels.
   * @param   h   The height of the mask, in pixels.
   */
  private function createImageClipMask (w:Number,
                                        h:Number):Void {
    // Only create the mask if a valid width and height are specified.
    if (!(w > 0 && h > 0)) {
    	var a:Number=ow;
    	var b:Number=oh;
      return;
    }else{
    	var a:Number=w;
    	var b:Number=h;
    }
    // In the container, create a clip to act as the mask over the image.
    container_mc.createEmptyMovieClip("mask_mc", maskDepth);

    // Draw a rectangle in the mask.
    container_mc.mask_mc.moveTo(0, 0);
    container_mc.mask_mc.beginFill(0x0000FF);  // Use blue for debugging.
    container_mc.mask_mc.lineTo(a, 0);
    container_mc.mask_mc.lineTo(a, b);
    container_mc.mask_mc.lineTo(0, b);
    container_mc.mask_mc.lineTo(0, 0);
    container_mc.mask_mc.endFill();
    
    // Hide the mask (it will still function as a mask when invisible).
    container_mc.mask_mc._visible = false; 
  }

  /**
   * Creates the border around the image.
   *
   * @param   w        The width of the border, in pixels.
   * @param   h        The height of the border, in pixels.
   */

  /**
   * Loads a .jpeg file into the image viewer.
   *
   * @param   URL   The local or remote address of the image to load.
   */
  public function loadImage ():Void {
    imageLoader.loadClip(filename, container_mc.image_mc);
  }

  /**
   * MovieClipLoader handler. Triggered by imageLoader when data arrives.
   * 
   * @param   target        A reference to the movie clip for which 
   *                        progress is being reported.
   * @param   bytesLoaded   The number of bytes of target 
   *                        that have loaded so far.
   * @param   bytesTotal    The total size of target, in bytes.
   */
  public function onLoadProgress (target:MovieClip, 
                                  bytesLoaded:Number, 
                                  bytesTotal:Number):Void {
        dataLoaded = bytesLoaded;
		dataTotal = bytesTotal;
  }
  /**
   * MovieClipLoader handler. Triggered by imageLoader when loading is done.
   * 
   * @param   target   A reference to the movie clip for which 
   *                   loading has finished.
   */
  public function onLoadInit (target:MovieClip):Void {
  	 	 ow=target._width;
  	 	 oh=target._height; 
  	 	 createImageClipMask(mask_w, mask_h);
	     container_mc.image_mc.setMask(container_mc.mask_mc);
	     preloader.removePreload(this);
	   
  }

  /**
   * MovieClipLoader handler. Triggered by imageLoader when loading fails.
   *
   * 
   * @param   target   A reference to the movie clip for which 
   *                   loading failed.
   * @param   errorCode   A string stating the cause of the load failure.
   */
  public function onLoadError (target:MovieClip, errorCode:String):Void {
    if (errorCode == "URLNotFound") {
    	log.error("ERROR: File not found.");
    } else if (errorCode == "LoadNeverCompleted") {
    	log.error("ERROR: Load failed.");
    } else {
      // Catch-all to handle possible future errorCodes.
      log.error("Load error: " + errorCode);
    }
  }

  /**
   * Must be called before the com.marc.imageContent.ImageViewer instance is deleted.
   * Gives the instance a chance to destroy any resources it has created.
   */
  public function destroy ():Void {
    // Cancel load event notifications.
    imageLoader.removeListener(this);
    // Remove movie clips from Stage.
    container_mc.removeMovieClip();
  }
	public function getDataLoaded() : Number {
		return dataLoaded;
	}

	public function getDataTotal() : Number {
		return dataTotal;
	}

	public function setPreloader(pl : Preloader) : Void {
		preloader=pl;
	}
}
